home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
gamesrc
/
arasan_s
/
moveord.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-27
|
4KB
|
160 lines
// Copyright 1994 by Jon Dart. All Rights Reserved.
#include "moveord.h"
#include "scoring.h"
#include "rmove.h"
#include "constant.h"
#include "attacke.h"
#include "bearing.h"
#include "util.h"
#include "array.h"
static Move Killers[Constants::MaxPly];
inline void swap( Move moves[], const int i, const int j)
{
Move tmp = moves[j];
moves[j] = moves[i];
moves[i] = tmp;
}
#define SORT_LIMIT 8
int
Move_Ordering::score( Board &board, const Move &move )
{
int val = 0;
Square dest_square = move.DestSquare();
Square start_square = move.StartSquare();
Piece capture = board[dest_square];
if (!capture.IsEmpty())
{
ExtendedMove emove(board,move);
if (board.num_attacks(dest_square, board.OppositeSide()) == 0)
// attack on undefended piece
val += capture.Value();
else if (emove.Special() == ExtendedMove::Normal)
{
int est = attack_estimate(board,emove);
if (est > 0)
val += est;
else // losing capture
val += 40 + (est/16);
}
else // en-passant?
val += 32;
}
if (move == Killers[0])
val += 30;
ReversibleMove rmove(board, start_square, dest_square);
board.MakeMove(rmove);
val -= Scoring::positional_score(board);
if (board.CheckStatus() == Board::InCheck)
val += 25;
board.UndoMove(rmove);
return val;
}
void
Move_Ordering::order_moves(Board & board,
Move moves[], const int num_moves,
const int ply, const Move & best_move)
{
if (num_moves == 0)
return;
if (ply > 0)
{
// We can't afford a full sort of the moves at deeper plies.
// So we move promising moves towards the front, then sort
// the first few moves.
Array <int> scores(SORT_LIMIT);
int j = 0, i = 0;
Move tmp;
for (i = 0; i < num_moves && j < SORT_LIMIT; i++)
{
int score = 0;
const Square dest = moves[i].DestSquare();
const Square start = moves[j].StartSquare();
const Piece capture = board[dest];
if (moves[i] == best_move)
{
swap(moves,i,0);
scores[0] = Constants::BIG;
}
else if (!capture.IsEmpty())
{
int start_val;
if (board[start].Type() == Piece::King)
start_val = Piece::Value(Piece::Pawn);
else
start_val = board[start].Value();
int capture_val = capture.Value();
if (Scoring::check_en_prise(board,dest,board[dest]))
// piece appears to be en prise
score = capture_val;
else if (capture_val > start_val)
score = capture_val - start_val;
else
score += 30 + (capture_val - start_val)/16;
if (moves[i] == Killers[ply])
score += 30;
if (i != j)
{
swap(moves,i,j);
}
scores[j] = score;
++j;
}
else if (j < SORT_LIMIT)
{
// not a capture move
if (moves[i] == Killers[ply])
score += 30;
if (score)
{
scores[j] = score;
swap(moves,i,j);
++j;
}
}
}
if (j > 1)
sort_moves(moves,(int*)scores.get_data(),Util::Min(j,SORT_LIMIT));
}
else
{
// ply == 0
Array<int> scores(num_moves);
scores[0] = 1000; // p.v. move
for (int i = 1; i < num_moves; i++)
{
scores[i] = score(board,moves[i]);
}
sort_moves(moves, (int*)scores.get_data(), num_moves);
}
}
void
Move_Ordering::clear_killer()
{
for (int i = 0; i < Constants::MaxPly; i++)
Killers[i].MakeNull();
}
void
Move_Ordering::set_killer(ExtendedMove & move, const unsigned ply)
{
Killers[ply] = move;
}
void
Move_Ordering::get_killer(Move & move, const unsigned ply)
{
move = Killers[ply];
}